
package org.epsi.blokus;

import java.util.Observable;
import java.util.Observer;
import org.epsi.blokus.commun.Message;
import org.epsi.blokus.joueur.Client;
import org.epsi.blokus.joueur.OnlineClient;
import org.epsi.blokus.joueur.OnlineOpponent;
import org.epsi.blokus.joueur.Opponent;
import org.epsi.blokus.joueur.Player;
import org.epsi.blokus.tools.IConstantes;
import org.epsi.blokus.tools.Log;


public class OnlineGame implements Runnable, IConstantes, Observer {

    private OnlineClient  client;
    private OnlineOpponent  opponent;

    public static enum T_ETAT_PARTIE { ON, OFF };
    private T_ETAT_PARTIE etat;

    public OnlineGame(Client client, Opponent opponent) {
        this.client = (OnlineClient) client;
        this.opponent = (OnlineOpponent) opponent;
        this.etat = T_ETAT_PARTIE.ON;

    }

    
    public void run() {
        
        Log.out("OnlineGame : Lancement");

        try {

            // On commence à jouer quand les 2 joueurs ont initialisés leur partie.
            this.client.getSemInitialisationJoueur().acquire();
            Log.out("Client ready");
            this.opponent.getSemInitialisationJoueur().acquire();
            Log.out("Les deux adversaires sont prets !");

            // Le maitre demande au serveur d'attribuer les tours
            if (this.client.isMaster()) this.client.envoyerMessagePret();

            while (this.etat != T_ETAT_PARTIE.OFF)
            {
                // Vérification du temps restant
                if (this.client.isTimeOut())
                {
                    Log.out("J'ai perdu par timeout");

                    // Le joueur en timeout perd
                    this.client.changeBehaviorLoose();
                    this.opponent.changeBehaviorWin();

                    // Notifier que l'adversaire gagne
                    this.client.envoyerMessageTimeout();
                    
                    this.etat = T_ETAT_PARTIE.OFF;
                }

                // Le dernier coup était-il victorieux ?
                if (this.client.isWinner())
                {
                     Log.out("J'ai gagné !");

                    this.client.changeBehaviorWin();
                    this.client.changeBehaviorLoose();

                    // Notifier que l'on gagne
                    this.client.envoyerMessageGagnant();
                            
                    this.etat = T_ETAT_PARTIE.OFF;
                }
            }
        }
        catch (InterruptedException ex) {
            Log.out(ex.getMessage());
            this.etat = T_ETAT_PARTIE.OFF;
        }

    }

    
    // Messages reçus du serveur
    public void update(Observable o, Object message) {
        Message mess = (Message)message;

        System.out.println(mess.debug());
        
        switch (mess.getTypeMessage())
        {
            case infos_adversaires:
                Log.out("Infos de l'adversaire recues");

                String pseudo = (String)mess.getObject("PSEUDO");
                String avatar = (String)mess.getObject("AVATAR");
                
                this.opponent.isReady(pseudo, avatar);
            break;

            case a_toi_de_jouer:
                Log.out("C'est à moi de joueur");

                if (mess.getObject("LIG")!=null && mess.getObject("COL")!=null)
                {
                    Integer lig = (Integer)mess.getObject("LIG");
                    Integer col = (Integer)mess.getObject("COL");
                    Log.out("Mon adversaire a joué en "+col+"/"+lig);
                    this.opponent.ajouterCoup(col, lig);
                }

                client.notifierTourDeJeu();
            break;

            case en_attente:
                client.notifierFinTourDeJeu();
            break;

            case gagnant:
                 this.client.changeBehaviorWin();
                 this.client.changeBehaviorLoose();
            break;

            case perdant:
                this.client.changeBehaviorLoose();
                this.opponent.changeBehaviorWin();
            break;

            case chat_ingame_recevoir:
                String txt = (String) mess.getObject("MESSAGE");
                Log.out("Chat recu : "+txt);
                this.opponent.ajouterChat(txt);
            break;
        }
    }
}
